package com.micro.service.auth.server.login.wechat;

import com.google.common.collect.Maps;
import com.micro.service.account.share.dto.UserBaseDto;
import com.micro.service.account.share.dto.UserWechatDto;
import com.micro.service.account.share.service.UserBaseService;
import com.micro.service.auth.server.exception.AccountCenterException;
import com.micro.service.common.enums.UserStatusEnum;
import com.micro.service.common.exception.JiangHuException;
import com.micro.service.common.utils.HttpClientUtil;
import com.micro.service.common.utils.HttprequestUtils;
import com.micro.service.common.utils.ImeiUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;

/**
 * @author lvxiucai
 * @description 微信登录过滤器
 * @date 2019/9/24
 */
@Slf4j
public class WechatAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    private String openidParameter = "openid";
    private final String defaultHeadImg = "https://image.qiluyidian.mobi/huifutouxiang@2x.png";
    @Autowired
    private UserBaseService userBaseService;

    @Autowired
    private AuthenticationManager authenticationManager;

    public WechatAuthenticationFilter(){
        super(new AntPathRequestMatcher("/wechat/login", "POST"));
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
        if (!request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
        }
        //获取微信登录请求参数
        Map<String,Object> requestMap = HttprequestUtils.getRequestMap(request);
        String accessToken =  requestMap.get("accessToken")!=null?requestMap.get("accessToken").toString():null;
        String openId = requestMap.get("openId")!=null?requestMap.get("openId").toString():null;

        if(StringUtils.isNotBlank(accessToken) && StringUtils.isNotBlank(openId)){
            //从微信开放平台获取微信用户信息
//            Map<String,String> map = Maps.newHashMap();
//            map.put("access_token",accessToken);
//            map.put("openid",openId);
//            Map<String,Object> resultMap = HttpClientUtil.doGet("https://api.weixin.qq.com/sns/userinfo",map);
            Map<String,Object> resultMap = Maps.newHashMap();
            resultMap.put("access_token",accessToken);
            resultMap.put("openid",openId);
            resultMap.put("unionid", "unionid_"+ RandomUtils.nextInt());

            UserWechatDto userWechatDto = new UserWechatDto();
            userWechatDto.setNickName(resultMap.get("nickname")==null?"壹粉520":resultMap.get("nickname").toString());
            if(resultMap.get("unionid") != null){
                userWechatDto.setUnionid(resultMap.get("unionid")==null?null:resultMap.get("unionid").toString());
                userWechatDto.setSex(resultMap.get("sex")==null?1:Integer.parseInt(resultMap.get("sex").toString()));
                userWechatDto.setOpenid(openId);
                userWechatDto.setImei(ImeiUtils.getImeiFromHeaders(request));
                userWechatDto.setHeadImg(resultMap.get("headimgurl")==null?defaultHeadImg:resultMap.get("headimgurl").toString());
                UserBaseDto userBaseDto = userBaseService.checkWxExistsAndRegistry(userWechatDto);
                if(userBaseDto != null && UserStatusEnum.IS_DEL.getStatus().equals(userBaseDto.getStatus())){
                    throw new AccountCenterException("用户已注销");
                }
                WechatAuthenticationToken authenticationToken = new WechatAuthenticationToken(openId);
                setDetails(request,authenticationToken);
                return this.getAuthenticationManager().authenticate(authenticationToken);
            }else{
                throw new JiangHuException("微信用户信息获取失败");
            }
        }else {
            throw new JiangHuException("微信access_token和openid不能为空");
        }

    }

    /**
     * Provided so that subclasses may configure what is put into the
     * authentication request's details property.
     *
     * @param request
     *            that an authentication request is being created for
     * @param authRequest
     *            the authentication request object that should have its details
     *            set
     */
    protected void setDetails(HttpServletRequest request, WechatAuthenticationToken authRequest) {
        authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
    }
    public UserBaseService getUserBaseService() {
        return userBaseService;
    }

    public void setUserBaseService(UserBaseService userBaseService) {
        this.userBaseService = userBaseService;
    }

    @Override
    public AuthenticationManager getAuthenticationManager() {
        return authenticationManager;
    }

    @Override
    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }
}
